/*
 * @Author: shuowang1991@163.com 
 * @Date: 2025-01-27 13:37:37 
 * @Last Modified by: wangshuo
 * @Last Modified time: 2025-05-27 15:26:51
 */
const { app, BrowserWindow, ipcMain,Tray, Menu, dialog, globalShortcut } = require('electron');
const path = require('path');
const fs = require('fs');

let mainWindow, tray = null;
// 创建窗口
function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'), // 指定预加载脚本
      contextIsolation: true, // 开启上下文隔离（安全必备）
      nodeIntegration: false  // 禁用直接 Node.js 访问
    }
  })

  // 隐藏菜单
  mainWindow.setMenu(null);

  // 加载本地页面（开发时可替换为本地服务地址，如 http://localhost:3000）
  mainWindow.loadFile(path.join(__dirname, 'src', 'index.html'));

  // 窗口关闭事件处理
  mainWindow.on('close', (event) => {
    if (!app.isQuiting) {
      event.preventDefault()
      const choice = dialog.showMessageBoxSync(mainWindow, {
        type: 'question',
        buttons: ['直接退出', '最小化到托盘'],
        title: '确认',
        message: '您要如何操作？',
        defaultId: 1
      })
      
      if (choice === 0) {
        app.isQuiting = true
        app.quit()
      } else {
        mainWindow.hide()
      }
    }
  })
}

// 创建系统托盘（第一个需求）
function createTray() {
  tray = new Tray(path.join(__dirname, 'logo.png')); // 需要准备一个图标文件
  const contextMenu = Menu.buildFromTemplate([
    {
      label: '设置',
      click: () => {
        mainWindow.webContents.send('renderer-action', {
          type: 'openSettings',
          data: 'openSettings'
        })
      }
    },
    {
      label: '清除缓存',
      click: () => {
        // 清除缓存逻辑
        mainWindow.webContents.session.clearCache().then(() => {
          dialog.showMessageBoxSync(mainWindow, {
            title: '缓存清除',
            message: '缓存已清除！'
          })
        })
      }
    },
    {
      label: '退出',
      click: () => {
        app.isQuiting = true
        app.quit()
      }
    }
  ])

  tray.setToolTip('列控数据管理平台')
  tray.setContextMenu(contextMenu)

  // 双击托盘图标显示窗口
  tray.on('double-click', () => {
    mainWindow.show()
  })
}

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})

// 初始化
app.whenReady().then(() => {
  createWindow();
  createTray();

  // 注册快捷键
  registerShortcuts();
});

// 处理完全退出
app.on('before-quit', () => {
  app.isQuiting = true
})

// 应用退出时释放所有快捷键
app.on('will-quit', () => {
  globalShortcut.unregisterAll()
})

// 注册快捷键
function registerShortcuts() {
  // 注册 Ctrl+Alt+I 打开开发者工具
  const ret = globalShortcut.register('Control+Alt+I', () => {
    if (mainWindow) {
      mainWindow.webContents.openDevTools()
    }
  })

  // 检查快捷键是否注册成功
  if (!ret) {
    console.error('快捷键注册失败')
  }
}


// ******************* IPC 通信处理 *******************

// 获取安装目录中的 Data 文件夹路径
function getDataPath() {
  if (app.isPackaged) {
    // 生产环境：安装目录/Data
    return path.join(path.dirname(app.getPath('exe')), 'Resources')
  } else {
    // 开发环境：项目根目录/data
    return path.join(__dirname, 'resources')
  }
}
// 工具函数：前补零
function PrefixZero(num, n) {
  return (Array(n).join('0') + num.toString(16)).slice(-n);
}
// 是否存在加密狗
ipcMain.handle('checkIfLock', () => {
  return new Promise((resolve, reject) => {
    const lockFilePath = path.join(getDataPath(), 'lock.json');
    fs.readFile(lockFilePath, (err, data) => {
      if (err) {
        console.error('读取文件时出错:', err);
        return false; // 读取失败 
      }
      const lockData = JSON.parse(data.toString());
      if (lockData.pwd === '123456') {
        return resolve(true); // 读取成功 
      } else {
        return resolve(false); // 读取失败
      }
    });
  }).catch(error => {
    console.error('读取文件时出错:', error);
    return false; // 读取失败
  });
})

// 是否捕获U盾
ipcMain.handle('captureUKey', () => {
  return new Promise((resolve, reject) => {
   let promiseAry = [];
    var count = 0;
    while (count++ < 20) {//连续5次都失败 才认为失败
      promiseAry.push(checkOnceUKey());
    }
    Promise.all(promiseAry).then((results) => {
      console.log('所有检查结果:', results);
      if (Array.isArray(results) && results.length > 0) {
        resolve({
          flag: results.filter(item => item.flag == false).length == 0 ? true: false,
          randomNum: results[results.length - 1].randomNum || ''
        })
      } else {
        resolve({
          flag: false,
          randomNum: ''
        })
      }
      
    }) 
  }).catch(error => {
    console.error('是否捕获U盾出错:', error);
    return false; // 读取失败
  })
})
// 单次检查U盾
function checkOnceUKey() {
  return new Promise((resolve, reject) => {
    let flag = false;
    let randomNum = ''; // 随机数
    // 常量定义
    const DONGLE_SUCCESS = 0;
    const koffi = require('koffi');

    // 加载 DLL
    const dllPath = path.join(getDataPath(), 'Dongle_d.dll');
    const dongleLib = koffi.load(dllPath);

    // 定义结构体字段偏移量（单位：字节）
    const InfoStructOffsets = {
      m_Ver: 0,
      m_Type: 2,
      m_BirthDay: 4,
      m_Agent: 12,
      m_PID: 16,
      m_UserID: 20,
      m_HID: 24,
      m_IsMother: 32,
      m_DevType: 36
    };

    const InfoStructSize = 40;

    const Dongle_Enum = dongleLib.func('int Dongle_Enum(void*, int*)');
    const Dongle_Open = dongleLib.func('int Dongle_Open(int*, int)');
    const Dongle_ResetState = dongleLib.func('int Dongle_ResetState(int)');
    const Dongle_GenRandom = dongleLib.func('int Dongle_GenRandom(int, int, void*)');
    const Dongle_Close = dongleLib.func('int Dongle_Close(int)');

    // 初始化缓冲区
    const dongleInfo = Buffer.alloc(1024); // 假设最多 25 个设备（1024 / 40 ≈ 25）
    const countBuffer = Buffer.alloc(4);
    countBuffer.writeInt32LE(0, 0);

    // 1️⃣ 枚举设备
    let result = Dongle_Enum(dongleInfo, countBuffer);
    console.log(`** Dongle_Enum **: 0x${result.toString(16).padStart(8, '0')}`);

    if (result !== DONGLE_SUCCESS) {
      console.error(`** Enum errcode **: 0x${result.toString(16).padStart(8, '0')}`);
      flag = false;
    }

    const deviceCount = countBuffer.readInt32LE(0);
    console.log(`** Find Device **:  ${deviceCount}`);

    if (deviceCount === 0) {
      console.log('** No Device **');
      flag = false;
    }

    // 3️⃣ 打开设备
    const handleBuffer = Buffer.alloc(4);
    result = Dongle_Open(handleBuffer, 0);
    const handle = handleBuffer.readInt32LE(0);
    console.log(`** Dongle_Open **: 0x${result.toString(16).padStart(8, '0')}`);
    if (result !== DONGLE_SUCCESS) {
      console.error(`** Open Failed **`);
      flag = false;
    } else {
      console.log(`** Open Success **: [handle=0x${handle.toString(16).padStart(8, '0')}]`);
      randomNum = `0x${handle.toString(16).padStart(8, '0')}`;
      Dongle_Close(handle);
      flag = true;
    }

    // 4️⃣ 重置 COS 状态
    /*
    result = Dongle_ResetState(handle);
    console.log(`Dongle_ResetState 返回值: 0x${result.toString(16).padStart(8, '0')}`);
    if (result !== DONGLE_SUCCESS) {
      console.error(`重置 COS 状态失败`);
      Dongle_Close(handle);
      return;
    }
    console.log('重置 COS 状态成功');
    */
  
    // 5️⃣ 生成随机数
    // const randomLen = 16;
    // const randomBuffer = Buffer.alloc(randomLen);
    // result = Dongle_GenRandom(handle, randomLen, randomBuffer);
    // console.log(`Dongle_GenRandom : 0x${result.toString(16).padStart(8, '0')}`);
    // if (result !== DONGLE_SUCCESS) {
    //   console.error(`生成随机数失败`);
    //   Dongle_Close(handle);
    // } else {
    //   randomNum = randomBuffer.toJSON().data.map(b => PrefixZero(b, 2)).join(' ').toUpperCase();
    //   Dongle_Close(handle);
    // }
    //console.log(`随机数据: ${randomBuffer.toJSON().data.map(b => PrefixZero(b, 2)).join(' ').toUpperCase()}`);
    /*
    // 6️⃣ 关闭设备
    result = Dongle_Close(handle);
    console.log(`Dongle_Close 返回值: 0x${result.toString(16).padStart(8, '0')}`);
    if (result !== DONGLE_SUCCESS) {
      console.error(`关闭设备失败`);
      return;
    }
    console.log('成功关闭设备');
    */
   resolve({
    flag,
    randomNum
   })
  }).catch(err => {
    console.error('单次读取U盾失败:', err);
    return false; // 读取失败
  })
}

// 是否关闭窗口
ipcMain.handle('closeWindow', () => {
  app.quit();
})

// 暴露获取数据路径的 IPC 接口
ipcMain.handle('get-data-path', () => {
  return app.isPackaged
    ? path.join(path.dirname(app.getPath('exe')), 'Resources')
    : path.join(__dirname, 'resources')
})


